﻿using System;

namespace SpatialHashLib
{
    // source: http://www.eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx
    /// <summary>
    /// One-at-a-time hash
    /// </summary>
    internal struct HashFunction
    {
        int hashCode;

        HashFunction HashByte(byte val)
        {
            hashCode += val;
            hashCode += hashCode << 10;
            hashCode ^= hashCode >> 6;
            return this;
        }

        HashFunction HashFinish()
        {
            hashCode += hashCode << 3;
            hashCode ^= hashCode >> 11;
            hashCode += hashCode << 15;
            return this;
        }

        public HashFunction Hash(int val)
        {
            HashByte((byte)val);
            HashByte((byte)(val >> 8));
            HashByte((byte)(val >> 16));
            HashByte((byte)(val >> 24));
            HashFinish();

            return this;
        }

        public HashFunction Hash(string val)
        {
            if(val == null || val.Length == 0)
                return this;

            for (int i = 0; i < val.Length; i++)
                HashByte((byte)val[i]);

            HashFinish();

            return this;
        }

        public HashFunction Hash<T>(T val)
        {
            return Hash(val.GetHashCode());
        }

        public int HashCode
        {
            get { return hashCode; }
        }
    }
}
